﻿using XYS.Core.Models;
using XYS.Service.Core.Service;

namespace XYS.Core.Util;

public static partial class Extention
{

    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public static ResultModel<T> AcquireLock<T>(this LockService lockService, string lockKey, Func<T> action)
    {
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = @lock.Acquire;
        if (!lockFlag) return ResultModel<T>.Failed("锁资源未获取");

        try
        {
            var result = action();
            return ResultModel.Successed(result);
        }
        catch (Exception ex) { return ResultModel.Failed<T>(ex); }
    }

    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public static ResultModel AcquireLock(this LockService lockService, string lockKey, Action action)
    {
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = @lock.Acquire;
        if (!lockFlag) return ResultModel.Failed("锁资源未获取");

        try
        {
            action();
            return ResultModel.Success;
        }
        catch (Exception ex) { return ResultModel.Failed(ex); }
    }



    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="taskTimeout">获取锁的超时时间</param>
    /// <param name="validTime">持有锁时间（默认1分钟）</param>
    /// <param name="action"></param>
    /// <returns></returns>
    public static ResultModel<T> AcquireLock<T>(this LockService lockService, string lockKey, TimeSpan taskTimeout, TimeSpan? validTime, Func<T> action)
    {
        if (validTime == null) validTime = TimeSpan.FromMinutes(1);
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = @lock.Take(taskTimeout, validTime);
        if (!lockFlag) return ResultModel<T>.Failed("锁资源未获取");

        try
        {
            var result = action();
            return ResultModel.Successed(result);
        }
        catch (Exception ex) { return ResultModel.Failed<T>(ex); }
    }





    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="actionAsync"></param>
    /// <returns></returns>
    public static async Task<ResultModel> AcquireLockAsync(this LockService lockService, string lockKey, Func<Task> actionAsync)
    {
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = await @lock.AcquireAsync.ConfigureAwait(false);
        if (!lockFlag) return ResultModel.Failed("锁资源未获取");

        try
        {
            await actionAsync().ConfigureAwait(false);
            return ResultModel.Success;
        }
        catch (Exception ex) { return ResultModel.Failed(ex); }
    }

    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="actionAsync"></param>
    /// <returns></returns>
    public static async Task<ResultModel<T>> AcquireLockAsync<T>(this LockService lockService, string lockKey, Func<Task<T>> actionAsync)
    {
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = await @lock.AcquireAsync.ConfigureAwait(false);
        if (!lockFlag) return ResultModel<T>.Failed("锁资源未获取");

        try
        {
            var result = await actionAsync().ConfigureAwait(false);
            return ResultModel.Successed(result);
        }
        catch (Exception ex) { return ResultModel.Failed<T>(ex); }
    }
    /// <summary>
    /// 加锁操作
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="taskTimeout">获取锁的超时时间</param>
    /// <param name="validTime">持有锁时间（默认1分钟）</param>
    /// <param name="actionAsync"></param>
    /// <returns></returns>
    public static async Task<ResultModel<T>> AcquireLockAsync<T>(this LockService lockService, string lockKey, TimeSpan taskTimeout, TimeSpan? validTime, Func<Task<T>> actionAsync)
    {
        if (validTime == null) validTime = TimeSpan.FromMinutes(1);
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = await @lock.TakeAsync(taskTimeout, validTime).ConfigureAwait(false);
        if (!lockFlag) return ResultModel<T>.Failed("锁资源未获取");

        try
        {
            var result = await actionAsync().ConfigureAwait(false);
            return ResultModel.Successed(result);
        }
        catch (Exception ex) { return ResultModel.Failed<T>(ex); }
    }


    /// <summary>
    /// 加锁操作
    /// </summary>
    /// 
    /// <param name="lockService"></param>
    /// <param name="lockKey"></param>
    /// <param name="taskTimeout">获取锁的超时时间</param>
    /// <param name="validTime">持有锁时间（默认1分钟）</param>
    /// <param name="actionAsync"></param>
    /// <returns></returns>
    public static async Task<ResultModel> AcquireLockAsync(this LockService lockService, string lockKey, TimeSpan taskTimeout, TimeSpan? validTime, Func<Task> actionAsync)
    {
        if (validTime == null) validTime = TimeSpan.FromMinutes(1);
        using var @lock = lockService.CreateLockService(lockKey);
        bool lockFlag = await @lock.TakeAsync(taskTimeout, validTime).ConfigureAwait(false);
        if (!lockFlag) return ResultModel.Failed("锁资源未获取");

        try
        {
            await actionAsync().ConfigureAwait(false);
            return ResultModel.Success;
        }
        catch (Exception ex) { return ResultModel.Failed(ex); }
    }

}